import { HttpParams } from '@angular/common/http';
import { BirefApiService } from './../../../api/biref-api.service';
import { BriefAdderComponent } from './../../../common-util/brief-adder/brief-adder.component';
import { PhaseTaskAdderComponent } from './../phase-task-adder/phase-task-adder.component';
import { PhasedTaskApiService } from './../../../api/phased-task-api.service';
import { PhasedTask, PhasedTaskParam, PhasedTaskWithChildren, PhasedTaskWithChildrenParam } from './../../../model/task';
import { Component, OnChanges, OnInit, SimpleChanges, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, } from '@angular/forms';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzTreeNodeOptions } from 'ng-zorro-antd/tree';
import { Router } from '@angular/router';

@Component({
  selector: 'app-phase-task-overview',
  templateUrl: './phase-task-overview.component.html',
  styleUrls: ['./phase-task-overview.component.less'],
  providers: [PhasedTaskApiService]
})
export class PhaseTaskOverviewComponent implements OnInit, OnChanges {

  searchFrom: FormGroup;
  taskSelectNode: Array<NzTreeNodeOptions> = [];
  taskList = new Array<TaskTableNode>();
  isTaskModalVisible = false;
  taskModalTitle = '添加工作';
  mapOfExpandedData: { [key: string]: TaskTableNode[] } = {};
  @ViewChild('taskAdder') taskAdder: PhaseTaskAdderComponent | undefined;
  @ViewChild('briefAdder') briefAdder: BriefAdderComponent | undefined;
  isTaskBriefVisible = false;
  isTableLoding = false;

  constructor(
    private fb: FormBuilder,
    private taskApi: PhasedTaskApiService,
    private message: NzMessageService,
    private router: Router,
    private briefApi: BirefApiService,
  ) {
    this.searchFrom = fb.group({
      name: [],
      target: [],
      tags: [],
      processStatus: [],
      importance: [],
      begin: [],
      end: []
    });

  }
  ngOnChanges(changes: SimpleChanges): void { }

  ngOnInit(): void {
    this.fetchData();
  }

  searchResult(): void {
    const searchObject: { [key: string]: any; } = {};
    for (const controlKey in this.searchFrom.controls) {
      if (controlKey === 'begin' ) {
        const beginValue = this.searchFrom.controls.begin.value;
        if (beginValue && beginValue.length > 0) {
          // tslint:disable-next-line: no-string-literal
          searchObject['beginStart'] = beginValue[0]?.toISOString();
          // tslint:disable-next-line: no-string-literal
          searchObject['beginFinish'] = beginValue[1]?.toISOString();
        }
      }
      if (controlKey === 'end') {
        const endValue = this.searchFrom.controls.end.value;
        if (endValue && endValue.length > 0) {
          // tslint:disable-next-line: no-string-literal
          searchObject['endStart'] = endValue[0]?.toISOString();
          // tslint:disable-next-line: no-string-literal
          searchObject['endFinish'] = endValue[1]?.toISOString();
        }
      }
      if (controlKey !== 'end' && controlKey !== 'begin') {
        const searchValue = this.searchFrom.controls[controlKey].value;
        if (searchValue) {
          searchObject[controlKey] = searchValue;
        }
      }

    }
    const searchParam = new HttpParams({
      fromObject: searchObject
    });
    this.taskApi.listWithChildren(searchParam).subscribe(
      tasks => {
        this.taskList = this.convertTableNode(tasks);
        this.taskList.forEach(item => this.mapOfExpandedData[item.key] = this.convertTreeToList(item));
      },
      err => {
        this.message.error('搜索工作错误');
        console.error(err);
      }
    );
  }

  restSearchFrom(e: MouseEvent): void {
    e.preventDefault();
    this.searchFrom.reset();
    this.fetchData();
  }

  collapse(array: TaskTableNode[], data: TaskTableNode, $event: boolean): void {
    if (!$event) {
      if (data.children) {
        data.children.forEach(d => {
          const target = array.find(a => a.key === d.key);
          if (target) {
            target.expand = false;
            this.collapse(array, target, false);
          }
        });
      } else {
        return;
      }
    }
  }

  addTask(): void {
    this.isTaskModalVisible = true;
    this.taskModalTitle = '添加工作';
  }



  handleAdderOk(): void {
    const data = this.taskAdder?.getData();
    if (data) {
      if (data.id) {
        this.editTask(data);
      } else {
        this.createTask(data);
      }
    }
  }

  createTask(data: PhasedTaskParam): void {
    this.taskApi.create(data).subscribe(
      response => {
        this.message.success('创建工作成功');
        this.fetchData();
        setTimeout(this.handleAdderCancel, 500);
      },
      err => {
        this.message.error('创建工作错误');
        console.error(err);
      }
    );
  }
  editTask(data: PhasedTaskParam): void {
    this.taskApi.update(data.id, data).subscribe(
      response => {
        this.message.success('编辑工作成功');
        this.fetchData();
        setTimeout(this.handleAdderCancel, 500);
      },
      err => {
        this.message.error('编辑工作错误');
        console.error(err);
      }
    );
  }

  handleAdderCancel = (): void => {
    this.taskAdder?.reset();
    this.isTaskModalVisible = false;
  }

  handleEditTask(data: TaskTableNode): void {
    this.taskModalTitle = '编辑工作';
    this.taskApi.fetchItem(parseInt(data.key, 10)).subscribe(
      task => {
        this.taskAdder?.setData(new PhasedTask(task));
        this.isTaskModalVisible = true;
      },
      err => {
        this.message.error('获取工作详情错误');
        console.error(err);
      }
    );
  }

  completeTask(data: TaskTableNode): void {
    this.taskApi.updateTaskProcessStatus(parseInt(data.key, 10), 1).subscribe(
      response => {
        this.message.success('操作成功');
        if (response.processStatus) {
          data.processStatus = response.processStatus;
        }
      },
      err => {
        this.message.error('操作失败');
        console.log(err);
      }
    );

  }

  deleteTask(key: string): void {
    this.taskApi.delete([parseInt(key, 10)]).subscribe(
      response => {
        this.message.success('删除成功！共删除' + response.length + '项工作');
        this.fetchData();
      }
    );
  }

  navigateToDetail(id: string): void {
    this.router.navigateByUrl('phaseTask/detail/' + id);
  }
  handleBriefAdder(item: TaskTableNode): void {
    this.briefAdder?.setPhaseTaskId(parseInt(item.key, 10));
    this.isTaskBriefVisible = true;
  }
  handleBriefCancel = (): void => {
    this.briefAdder?.reset();
    this.isTaskBriefVisible = false;
  }
  handleBriefOk(): void {
    const brief = this.briefAdder?.getValue();
    if (brief) {
      this.briefApi.create(brief).subscribe(
        response => {
          this.message.success('简报创建成功');
          setTimeout(this.handleBriefCancel, 500);
        },
        err => {
          this.message.error('创建简报失败');
          console.error(err);
        }
      );
    }

  }

  private fetchData(): void {
    this.isTableLoding = true;
    this.taskApi.listWithChildren().subscribe(
      tasks => {
        this.isTableLoding = false;
        this.taskSelectNode = this.convertSelectNode(tasks.map(param => new PhasedTaskWithChildren(param)));
        this.taskList = this.convertTableNode(tasks);
        this.taskList.forEach(item => this.mapOfExpandedData[item.key] = this.convertTreeToList(item));
      },
      err => {
        this.isTableLoding = false;
        this.message.error('获取工作列表数据错误');
        console.log(err);
      }
    );
  }

  private convertSelectNode(data: Array<PhasedTaskWithChildren>): Array<NzTreeNodeOptions> {
    const result: Array<NzTreeNodeOptions> = [];
    for (const item of data) {
      result.push(item.convertToNzTreeNodeOption());
    }
    return result;
  }

  private convertTableNode(data: Array<PhasedTaskWithChildrenParam>): Array<TaskTableNode> {
    const result = new Array<TaskTableNode>();
    for (const item of data) {
      const node: TaskTableNode = {
        key: item.id.toPrecision(),
        name: item.name,
        description: item.description ? item.description : '',
        target: item.target ? item.target : '',
        end: new Date(item.end),
        begin: new Date(item.begin),
        processStatus: item.processStatus ? item.processStatus : 0,
        importance: item.importance ? item.importance : 0,
        level: item.level ? item.level : 0,
      };
      if (item.children && item.children.length > 0) {
        node.children = this.convertTableNode(item.children);
      }
      result.push(node);
    }
    return result;
  }

  private convertTreeToList(root: TaskTableNode): TaskTableNode[] {
    const strack = new Array<TaskTableNode>();
    const result = new Array<TaskTableNode>();
    const hashMap = {};
    strack.push({ ...root, level: 0, expand: false });
    while (strack.length !== 0) {
      const node = strack.pop();
      if (node) {
        this.visitNode(node, hashMap, result);
        if (node.children) {
          for (let i = node.children.length - 1; i >= 0; i--) {
            strack.push({ ...node.children[i], level: node.level + 1, expand: false, parent: node });
          }
        }
      }
    }
    return result;
  }

  private visitNode(node: TaskTableNode, hashMap: { [key: string]: boolean }, array: TaskTableNode[]): void {
    if (!hashMap[node.key]) {
      hashMap[node.key] = true;
      array.push(node);
    }
  }

}

export interface TaskTableNode {
  key: string;
  name: string;
  description: string;
  target: string;
  end: Date;
  begin: Date;
  processStatus: number;
  importance: number;
  level: number;
  expand?: boolean;
  children?: TaskTableNode[];
  parent?: TaskTableNode;
}


